package com.sovphone.clevertools

import android.accessibilityservice.AccessibilityService
import android.app.*
import android.content.*
import android.graphics.Rect
import android.os.Build
import android.text.TextUtils
import android.util.Log
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Toast
import androidx.core.app.NotificationCompat
import java.util.*


/**
 * Author tianwei
 * Date：2020/12/4 10:48
 *
 * Description:
 */
class CleverService : AccessibilityService() {
    companion object {
        const val TAG: String = "CleverService"
        const val NOTIFICATION_ID = 1
        private var mInstance: CleverService? = null

        fun getInstance(): CleverService? {
            return mInstance;
        }
    }

    private var mBuilder: NotificationCompat.Builder? = null
    private var mNotificationManager: NotificationManager? = null
    var openClock: Boolean = false

    var intervalMillis: Long = 0//重复间隔
    var nextClockTimeInMillis: Long = 0
    var name: String = ""

    private fun cancelNotification() {
        if (mNotificationManager == null) {
            mNotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        }
        mNotificationManager!!.cancel(NOTIFICATION_ID)
    }

    private fun showNotification() {
        mNotificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
        if (mBuilder == null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val mChannel = NotificationChannel(
                    "muyu",
                    "闹钟",
                    NotificationManager.IMPORTANCE_HIGH
                )
                mBuilder =
                    NotificationCompat.Builder(this, "muyu")
                mNotificationManager?.createNotificationChannel(mChannel)
            } else {
                mBuilder = NotificationCompat.Builder(this, "muyu")
            }
            mBuilder?.setSmallIcon(R.mipmap.ic_launcher)
        }
        val mIntent = Intent(Constants.ACTION_CLOCK_STOP_RECEIVER)
        val pendingIntent = PendingIntent.getBroadcast(
            this,
            0,
            mIntent,
            PendingIntent.FLAG_CANCEL_CURRENT
        )
        mBuilder?.setContentIntent(pendingIntent)
        mBuilder?.setDeleteIntent(pendingIntent)
        mBuilder?.setAutoCancel(true)
        //        mBuilder.setFullScreenIntent(pendingIntent, true);//设置滑动式通知
        mBuilder?.setOngoing(true)
        updateNotification("定时打卡服务，请勿取消", "通知取消后，可能导致打卡程序不能正常运行")
    }

    /**
     * @param triggerAtMillis 首次执行时间
     */
    fun start(triggerAtMillis: Long, intervalMillis: Long, name: String) {
        this.intervalMillis = intervalMillis
        this.name = name
        if (TextUtils.isEmpty(name)) return
        clock(triggerAtMillis)
    }

    private fun clock(delayMillis: Long) {
        log("启动闹钟下次打卡时间:${DateUtils.format(delayMillis)}")
        nextClockTimeInMillis = delayMillis
        val alarmManager = getSystemService(Service.ALARM_SERVICE) as AlarmManager
        val intent = Intent(Constants.ACTION_CLOCK_START_RECEIVER)
        val mPendingIntent =
            PendingIntent.getBroadcast(this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager.setExact(
            AlarmManager.RTC_WAKEUP,
            delayMillis,
            mPendingIntent
        )
        updateNotification("正在执行定时打卡任务，请勿取消", "下次打卡时间:${DateUtils.format(delayMillis)}")
    }

    fun stop() {
        val alarmManager = getSystemService(Service.ALARM_SERVICE) as AlarmManager
        val intent = Intent(Constants.ACTION_CLOCK_STOP_RECEIVER)
        val mPendingIntent =
            PendingIntent.getBroadcast(this, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager.cancel(mPendingIntent)
        updateNotification("定时打卡服务，请勿取消", "")
    }

    fun updateNotification(title: String, text: String) {
        if (!TextUtils.isEmpty(title)) {
            mBuilder?.setContentTitle(title)
        }
        if (!TextUtils.isEmpty(text)) {
            mBuilder?.setContentText(text)
        }
        mNotificationManager?.notify(NOTIFICATION_ID, mBuilder?.build())
        log("[updateNotification] title: $title, text: $text")
    }

    val clockReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent?.action == Constants.ACTION_CLOCK_START_RECEIVER) {
                log("时间到，开始打卡")
                if (intervalMillis > 0) {//重复
                    clock(System.currentTimeMillis() + intervalMillis)
                }
                openClock = true
                restartApp(
                    "com.alibaba.android.rimet",
                    "com.alibaba.android.rimet.biz.LaunchHomeActivity"
                )
            } else {
                log("停止服务")
                openClock = false
            }
        }
    }

    private fun restartApp(pkg: String, cls: String) {
        log("[restartApp]")
        kill(pkg)
        val timer = Timer()
        timer.schedule(object : TimerTask() {
            override fun run() {
                start(pkg, cls)
            }
        }, 500)
    }

    private fun start(pkg: String, cls: String) {
        log("[start]")
        try {
            val newIntent = Intent(Intent.ACTION_MAIN)
            val componentName = ComponentName(pkg, cls)
            newIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            newIntent.component = componentName
            startActivity(newIntent)
        } catch (e: ActivityNotFoundException) {
            e.printStackTrace()
            Toast.makeText(this, "请检查是否安装钉钉", Toast.LENGTH_SHORT).show()
        }
    }

    private fun kill(pkg: String) {
        val activityManager =
            getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        activityManager.killBackgroundProcesses(pkg)
    }

    override fun onServiceConnected() {
        super.onServiceConnected()
        log("[onServiceConnected]")
        mInstance = this;
        val filter = IntentFilter(Constants.ACTION_CLOCK_START_RECEIVER)
        filter.addAction(Constants.ACTION_CLOCK_STOP_RECEIVER)
        registerReceiver(clockReceiver, filter)
        showNotification()
    }

    override fun onDestroy() {
        super.onDestroy()
        log("[onDestroy]")
        mInstance = null
        unregisterReceiver(clockReceiver)
    }

    override fun onInterrupt() {
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent?) {
        if (!openClock) return
        when (event?.eventType) {
            AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED -> {
                rootInActiveWindow?.let {
                    findChild(it)
                }
            }
        }
    }

    fun log(msg: Any) {
        Log.e(TAG, "$msg")
//        Logger.getInstance().log(
//            msg = "$TAG: $msg"
//        )
    }

    fun findChild(info: AccessibilityNodeInfo) {
        val count = info.childCount
        for (i in 0 until count) {
            val childInfo = info.getChild(i)
            val rect = Rect()
            val text = childInfo?.text?.toString()
            if ("钉钉" == text) {
                log(
                    "第 $i 个控件的子控件数：" + text + "，" + childInfo.getBoundsInScreen(rect) + ", rect = " + rect + ", parent = " + childInfo.parent.childCount
                )
                val performResult = childInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                log("钉钉 performResult = $performResult")
            } else if (name == text && childInfo.isVisibleToUser) {
                log(
                    "第 $i 个控件的子控件数：" + text + "，" + childInfo.getBoundsInScreen(rect) + ", rect = " + rect + ", parent = " + childInfo.parent.childCount
                )
                val performResult =
                    childInfo.parent?.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                log("$name performResult = $performResult")
            } else if ("考勤打卡" == text && childInfo.isVisibleToUser) {
                log(
                    "第 $i 个控件的子控件数：" + childInfo.text + "，" + childInfo.getBoundsInScreen(
                        rect
                    ) + ", rect = " + rect + ", parent = " + childInfo.parent.childCount
                )
                val performResult =
                    childInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                log("考勤打卡 performResult = $performResult")
            } else if ("下班打卡" == text && childInfo.isVisibleToUser) {
                log(
                    "第 $i 个控件的子控件数：" + childInfo.text + "，" + childInfo.getBoundsInScreen(
                        rect
                    ) + ", rect = " + rect + ", parent = " + childInfo.parent.childCount
                )
                val performResult = false
                    childInfo.parent?.performAction(AccessibilityNodeInfo.ACTION_CLICK) ?: false
                log("下班打卡 performResult = $performResult")
                openClock = false//打卡完毕重置
                updateNotification(
                    "下班打卡成功",
                    if (nextClockTimeInMillis > 0) "下次打卡时间:${DateUtils.format(nextClockTimeInMillis)}" else ""
                )
            } else if ("上班打卡" == text && childInfo.isVisibleToUser) {
                log(
                    "第 $i 个控件的子控件数：" + childInfo.text + "，" + childInfo.getBoundsInScreen(
                        rect
                    ) + ", rect = " + rect + ", parent = " + childInfo.parent.childCount
                )
                val performResult = false
                    childInfo.parent?.performAction(AccessibilityNodeInfo.ACTION_CLICK) ?: false
                log("上班打卡 performResult = $performResult")
                openClock = false//打卡完毕重置
                updateNotification(
                    "上班打卡成功",
                    if (nextClockTimeInMillis > 0) "下次打卡时间:${DateUtils.format(nextClockTimeInMillis)}" else ""
                )
            }

            if (childInfo != null) {
                findChild(childInfo)
            }
        }
    }

}